package com.wgb.movie.service.impl;

import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.wgb.movie.common.ErrorCode;
import com.wgb.movie.constant.CommonConstant;
import com.wgb.movie.exception.ThrowUtils;
import com.wgb.movie.mapper.MovieOrderMapper;
import com.wgb.movie.model.dto.movieOrder.MovieOrderQueryRequest;
import com.wgb.movie.model.entity.*;
import com.wgb.movie.model.vo.MovieOrderVO;
import com.wgb.movie.model.vo.UserVO;
import com.wgb.movie.service.*;
import com.wgb.movie.utils.SqlUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 订单服务实现
 *
 * @author <a href="https://github.com/liyupi">程序员鱼皮</a>
 * @from <a href="https://www.code-nav.cn">编程导航学习圈</a>
 */
@Service
@Slf4j
public class MovieOrderServiceImpl extends ServiceImpl<MovieOrderMapper, MovieOrder> implements MovieOrderService {

    @Resource
    private UserService userService;

    /**
     * 校验数据
     *
     * @param movieOrder
     * @param add        对创建的数据进行校验
     */
    @Override
    public void validMovieOrder(MovieOrder movieOrder, boolean add) {
        ThrowUtils.throwIf(movieOrder == null, ErrorCode.PARAMS_ERROR);
        // todo 从对象中取值
        Long id = movieOrder.getId();
        Long userId = movieOrder.getUserId();
        Long movieShowId = movieOrder.getMovieShowId();
        String seat = movieOrder.getSeat();
        BigDecimal price = movieOrder.getPrice();
        Integer orderStatus = movieOrder.getOrderStatus();


        // 创建数据时，参数不能为空
        if (add) {
            // todo 补充校验规则
            ThrowUtils.throwIf(movieShowId <= 0 || movieShowId == null, ErrorCode.PARAMS_ERROR, "电影场次id不合法");
            ThrowUtils.throwIf(StringUtils.isBlank(seat), ErrorCode.PARAMS_ERROR, "座位不能为空");
            ThrowUtils.throwIf(price == null || price.compareTo(BigDecimal.ZERO) <= 0, ErrorCode.PARAMS_ERROR, "价格不合法");
            ThrowUtils.throwIf(orderStatus == null || orderStatus < 0, ErrorCode.PARAMS_ERROR, "订单状态不合法");
        }
        // 修改数据时，有参数则校验
        // todo 补充校验规则

    }

    /**
     * 获取查询条件
     *
     * @param movieOrderQueryRequest
     * @return
     */
    @Override
    public QueryWrapper<MovieOrder> getQueryWrapper(MovieOrderQueryRequest movieOrderQueryRequest) {
        QueryWrapper<MovieOrder> queryWrapper = new QueryWrapper<>();
        if (movieOrderQueryRequest == null) {
            return queryWrapper;
        }
        // todo 从对象中取值
        Long id = movieOrderQueryRequest.getId();
        Long userId = movieOrderQueryRequest.getUserId();
        Long movieShowId = movieOrderQueryRequest.getMovieShowId();
        Integer orderStatus = movieOrderQueryRequest.getOrderStatus();
        String sortField = movieOrderQueryRequest.getSortField();
        String sortOrder = movieOrderQueryRequest.getSortOrder();
        // todo 补充需要的查询条件
        // 从多字段中搜索
        // 模糊查询
        // JSON 数组查询
        // 精确查询
        queryWrapper.eq(ObjectUtils.isNotEmpty(id), "id", id);
        queryWrapper.eq(ObjectUtils.isNotEmpty(userId), "userId", userId);
        queryWrapper.eq(ObjectUtils.isNotEmpty(movieShowId), "movieShowId", movieShowId);
        queryWrapper.eq(ObjectUtils.isNotEmpty(orderStatus), "orderStatus", orderStatus);
        // 排序规则
        queryWrapper.orderBy(SqlUtils.validSortField(sortField),
                sortOrder.equals(CommonConstant.SORT_ORDER_ASC),
                sortField);
        return queryWrapper;
    }

    @Resource
    private MovieShowService movieShowService;
    @Resource
    private MovieService movieService;
    @Resource
    private TheaterService theaterService;

    /**
     * 获取订单封装
     *
     * @param movieOrder
     * @param request
     * @return
     */
    @Override
    public MovieOrderVO getMovieOrderVO(MovieOrder movieOrder, HttpServletRequest request) {
        // 对象转封装类
        MovieOrderVO movieOrderVO = MovieOrderVO.objToVo(movieOrder);
        // todo 可以根据需要为封装对象补充值，不需要的内容可以删除
        // region 可选
        // 1. 关联查询用户信息
        Long userId = movieOrder.getUserId();
        User user = null;
        if (userId != null && userId > 0) {
            user = userService.getById(userId);
        }
        UserVO userVO = userService.getUserVO(user);
        movieOrderVO.setUser(userVO);
        // 2.电影名字、影院名字地址、影厅、上映时间
        MovieShow movieShow = movieShowService.getById(movieOrder.getMovieShowId());
        Movie movie = movieService.getById(movieShow.getMovieId());
        Theater theater = theaterService.getById(movieShow.getTheaterId());
        movieOrderVO.setMovieName(movie.getMovieName());
        movieOrderVO.setTheaterName(theater.getTheaterName());
        movieOrderVO.setTheaterAddress(theater.getTheaterAddress());
        movieOrderVO.setHallType(movieShow.getHallType());
        movieOrderVO.setShowTime(movieShow.getShowTime());
        // endregion

        return movieOrderVO;
    }

    /**
     * 分页获取订单封装
     *
     * @param movieOrderPage
     * @param request
     * @return
     */
    @Override
    public Page<MovieOrderVO> getMovieOrderVOPage(Page<MovieOrder> movieOrderPage, HttpServletRequest request) {
        List<MovieOrder> movieOrderList = movieOrderPage.getRecords();
        Page<MovieOrderVO> movieOrderVOPage = new Page<>(movieOrderPage.getCurrent(), movieOrderPage.getSize(), movieOrderPage.getTotal());
        if (CollUtil.isEmpty(movieOrderList)) {
            return movieOrderVOPage;
        }
        // 对象列表 => 封装对象列表
        List<MovieOrderVO> movieOrderVOList = movieOrderList.stream().map(movieOrder -> {
            return MovieOrderVO.objToVo(movieOrder);
        }).collect(Collectors.toList());

        // todo 可以根据需要为封装对象补充值，不需要的内容可以删除
        // region 可选
        // 1. 关联查询用户信息
        Set<Long> userIdSet = movieOrderList.stream().map(MovieOrder::getUserId).collect(Collectors.toSet());
        Map<Long, List<User>> userIdUserListMap = userService.listByIds(userIdSet).stream()
                .collect(Collectors.groupingBy(User::getId));
        // 2. 已登录，获取用户点赞、收藏状态

        // 填充信息
        movieOrderVOList.forEach(movieOrderVO -> {
            Long userId = movieOrderVO.getUserId();
            User user = null;
            if (userIdUserListMap.containsKey(userId)) {
                user = userIdUserListMap.get(userId).get(0);
            }
            movieOrderVO.setUser(userService.getUserVO(user));
            // 2.电影名字、影院名字地址、影厅、上映时间
            MovieShow movieShow = movieShowService.getById(movieOrderVO.getMovieShowId());
            Movie movie = movieService.getById(movieShow.getMovieId());
            Theater theater = theaterService.getById(movieShow.getTheaterId());
            movieOrderVO.setMovieName(movie.getMovieName());
            movieOrderVO.setTheaterName(theater.getTheaterName());
            movieOrderVO.setTheaterAddress(theater.getTheaterAddress());
            movieOrderVO.setHallType(movieShow.getHallType());
            movieOrderVO.setShowTime(movieShow.getShowTime());
        });
        // endregion

        movieOrderVOPage.setRecords(movieOrderVOList);
        return movieOrderVOPage;
    }

}
